import { fetch } from "@tauri-apps/plugin-http";
import { debug, error } from "@tauri-apps/plugin-log";
import { IMetarInfo } from "./interfaces/IMetarInfo";

const metarCache: Map<string, IMetarInfo> = new Map();

function getTimeFromMetar(metar: string): number {
    let ZERO = 0;
    const timeRegex: RegExp = new RegExp('(?<time>\\d{6})Z');
    const regRes = timeRegex.exec(metar);
    if (regRes === null) {
        return ZERO;
    }
    if (regRes.groups === undefined) {
        return ZERO;
    }
    const timeStr = regRes.groups.time;
    if (timeStr === undefined) {
        return ZERO;
    }
    if (timeStr.length < 6) {
        return ZERO;
    }
    const dayStr = timeStr.substring(0, 2);
    const hourStr = timeStr.substring(2, 4);
    const minuteStr = timeStr.substring(4, 6);
    const d = new Date;
    d.setUTCDate(Number(dayStr));
    d.setUTCHours(Number(hourStr), Number(minuteStr), 0, 0);
    return d.getTime();
}

export async function getVatsimMetar(...airports: Array<string>) {
    const result: Array<IMetarInfo> = [];
    try {
        airports = airports.map(airport => airport.trim().toUpperCase());
        for (let i = 0; i < airports.length; i++) {
            const airport = airports[i];
            const cache = metarCache.get(airport);
            if (cache != undefined && Date.now() - cache.time < 30 * 60 * 1000) {
                result.push(cache);
                airports.splice(i, 1);
            }
        }
        if (airports.length === 0) {
            return result;
        }
        const param = airports.join(',');
        const res = await fetch(`https://metar.vatsim.net/${param}`);
        const rawMetarInfo = await res.text();
        const metarArray = rawMetarInfo.split('\n');
        for (const metar of metarArray) {
            const code = metar.substring(0, 4);
            const info: IMetarInfo = {
                code,
                metar,
                time: getTimeFromMetar(metar),
            };
            result.push(info);
            debug(`updating cache, set ${code} to ${metar}`);
            metarCache.set(code, info);
        }
        return result;
    } catch (err) {
        error("failed to fetch Metar" + err);
        return result;
    }
}